package com.rtf.framework.es.service;

import com.rtf.framework.es.common.*;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.sort.SortBuilder;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * ElasticSearch操作服务
 * @Author : lwq
 * @Date : 2021-06-02
 * @Modified By
 */
public interface AppElasticSearchService<T extends AppEsEntity> {

    /**
     * 创建索引，新版ES插入数据时自动创建
     *
     * @param index      索引
     * @param shardNum   主分片数量
     * @param replicaNum 副本数量
     * @return
     */
    boolean createIndex(String index, Map<String,?> mapping, Integer shardNum, Integer replicaNum);

    /**
     * 获取索引
     *
     * @throws IOException
     */
    GetIndexResponse getIndex(String index);

    /**
     * 判断是否拥有某个索引
     *
     */
    Boolean existsIndex(String index);

    /**
     * 删除索引
     */
    boolean deleteIndex(String index);

    /**
     * 更新单条数据
     */
    void updateDocument(String index, T esEntity);

    /**
     * 更新单条数据
     */
    void updateDocument(String index, Map<String, Object> params);

    /**
     * 批量更新
     *
     * @param index
     * @param list
     * @return
     * @throws IOException
     */
    void updateBatch(String index, List<Map<String, Object>> list);

    /**
     * 批量更新数据
     *
     * @param index
     * @param list
     * @return
     */
    void updateBatchDocument(String index, List<T> list);

    /**
     * 批量更新
     *
     * @param index
     * @param list
     * @return BulkResponse
     * @throws IOException
     */
    void updateBatchByScript(String index, List<AppEsScriptInfo> list);

    /**
     * 批量更新
     *
     * @param index
     * @param queryBuilder  查询条件
     * @param batchSize     批量更改大小
     * @throws IOException
     */
    void updateByQuery(String index, QueryBuilder queryBuilder, Integer batchSize, Map<String, Object> document);

    /**
     * 批量更新
     *
     * @param index
     * @param queryBuilder 查询条件
     * @param batchSize    批量更新大小
     * @throws IOException
     */
    void updateByQuery(String index, QueryBuilder queryBuilder, Integer batchSize, Script script);

    /**
     * 保存信息
     *
     * @param index      索引名称
     * @param esEntities
     * @return IndexResponse
     * @throws Exception
     * @author lwq
     */
    void insertDocument(String index, T esEntities);


    /**
     * 批量插入数据
     */
    void insertBatchDocument(String index, List<T> esEntities);

    /**
     * 通过ID获取数据
     *
     * @param index         索引，类似数据库
     * @param id            数据ID
     * @param includeFields 需要显示的字段
     * @param excludeFields 不需要显示的字段
     * @return Map
     * @author lwq
     */
    Map<String, Object> getDataById(String index, String id, String[] includeFields, String[] excludeFields);

    /**
     * 通过ID获取数据
     *
     * @param index 索引，类似数据库
     * @param id    数据ID
     * @return
     * @author lwq
     */
    Map<String, Object> getDataById(String index, String id);

    /**
     * 通过ID获取数据
     *
     * @param index         索引，类似数据库
     * @param id            数据ID
     * @param includeFields 需要显示的字段
     * @return
     */
    Map<String, Object> getDataByIdIncludeFields(String index, String id, String[] includeFields);

    /**
     * 通过ID获取数据
     *
     * @param index         索引，类似数据库
     * @param id            数据ID
     * @param excludeFields 不需要显示的字段
     * @return
     */
    Map<String, Object> getDataByIdExcludeFields(String index, String id, String[] excludeFields);
    /**
     * 根据id获取详情
     *
     * @param index     索引名称
     * @param id        id
     * @param tClass
     * @return
     * @throws Exception
     */
    T getEntityById(String index, String id, Class<T> tClass);

    /**
     * 根据查询方式获取某个索引下的文档个数
     *
     * @param index
     * @param queryBuilder
     * @return
     */
    long queryCount(String index, QueryBuilder queryBuilder);

    /**
     * 查看文档是否存在
     *
     * @param id
     * @return
     * @throws IOException
     */
    Boolean existsDocument(String index, String id);

    /**
     * 多条件组合查询
     * @param index         索引名称
     * @param queryBuilder  查询条件
     * @param resultClass   返回结果类型
     * @param size          查询数量
     * @return
     * @throws IOException
     */
    List<T> searchDocument(String index, QueryBuilder queryBuilder, Class<T> resultClass, int size);

    /**
     * scroll 查询
     * @param index             索引名
     * @param scroll            滚动查询有效时间设置
     * @param queryBuilder      查询信息
     * @param size              查询条数
     * @param sortBuilders      排序条件
     * @param resultClass       返回类型
     * @return
     */
    AppEsScrollPage<T> queryScrollPage(String index, Scroll scroll, QueryBuilder queryBuilder, int size, List<SortBuilder> sortBuilders, Class<T> resultClass);

    /**
     *
     * @param scroll
     * @param scrollId
     * @param size
     * @param resultClass
     * @return
     */
    AppEsScrollPage<T> queryScrollPage(Scroll scroll, String scrollId, int size, Class<T> resultClass);

    /**
     * 统计查询
     *
     * @param index              索引
     * @param queryBuilder       查询条件
     * @param aggregationBuilder
     * @return
     * @throws Exception
     */
    Aggregations aggregation(String index, QueryBuilder queryBuilder, AggregationBuilder aggregationBuilder);

    /**
     * 使用分词查询,并分页
     *
     * @param startPage     当前页         从0开始
     * @param pageSize      每页显示条数
     * @param sortBuilders  排序字段
     * @return
     */
    AppEsPage<T> queryPage(String index, int startPage, int pageSize, QueryBuilder queryBuilder, List<SortBuilder> sortBuilders, Class<T> resultClass);

    /**
     * 使用分词查询,并分页
     *
     * @param startPage     当前页            从0开始分页
     * @param pageSize      每页显示条数
     * @param sortBuilders  排序字段
     * @return
     */
    AppEsPage<Map> queryPage(String index, int startPage, int pageSize, QueryBuilder queryBuilder, List<SortBuilder> sortBuilders, String[] includeFields);

    /**
     * 删除单条数据
     */
    void deleteDocument(String index,  String id);

    /**
     * 批量删除数据
     *
     * @param ids
     * @return
     * @throws IOException
     */
    void deleteBatchDocument(String index, List<String> ids);

    /**
     * 公共批量bulk处理数据 插入、更新、删除
     */
    void bulkBatchDocument(BulkRequest bulkRequest);
}
